var fs = require("fs");
var process = require("process");
var iconv = require("iconv-lite");
var program = require("commander");
var outFile = "out";
var resourceDir = "./resource/"
var fileVersion = "V1.0.0";
var maxWordCount;
const magic_head = "trendit.aud";

program
  .option("文件格式说明: [96字节全0保留数据][16字节ASCII版本号][2字节BCD总字数][[[2字节UNICODE中文字符][2字节BCD文件长度][2字节BCD文件数据偏移量]]...][[文件数据]...]")
  .option('-r, --resourceDir [String]', '资源目录')
  .option('-m --maxWordCount [Integer]', '最大字数限制')
  .option('-o, --outFile [String]', '输出文件')
  .option('-v, --fileVersion [String]', '文件版本')
  .parse(process.argv);
if(program.resourceDir) {
    resourceDir = `./${program.resourceDir}/`;
}

if(!program.outFile) {
    throw new Error("未指定输出文件，请输入-h查看帮助信息")
} 
outFile = program.outFile;

if(!program.fileVersion) {
    throw new Error("未指定文件版本，请输入-h查看帮助信息");
} 
fileVersion = program.fileVersion;

if(!program.maxWordCount) {
    throw new Error("未指定最大字数限制，请输入-h查看帮助信息");
}
maxWordCount = parseInt(program.maxWordCount);

console.log("==>", program.fileVersion, "<===");

function loadFileMapper(mapperPath) {
    if(!fs.existsSync(mapperPath)) {
        throw new Error(`文件映射表：${mapperPath} 不存在`)
    }
    let buffer = fs.readFileSync(mapperPath);

    return JSON.parse(buffer);
}

function prefixHexInteger(num, length) {
    let hexStr = (Array(length).join('0') + num.toString(16)).slice(-length);
    return Buffer.from(hexStr, "hex");
}

const fileMapper = loadFileMapper(resourceDir + "file_mapper.json");

const handler = fs.openSync(outFile, "w+");

let writePivot = 0;
let writeLen = 0;

if(fileMapper.length > maxWordCount) {
    throw new Error(`总字数不能超过${maxWordCount}, 当前文件包含${fileMapper.length}个字`);
}
console.log("开始生成音频映射文件...");

console.log("写入96字节保留字符");
var blank = new Buffer.alloc(96, 0);

writeLen = fs.writeSync(handler, blank, 0, blank.length, writePivot);
if(writeLen != blank.length) {
    throw new Error(`写入96字节保留空字符失败 ${writeLen} of ${blank.length}`);
}
writePivot += writeLen;

console.log(`写入文件魔数`);
fs.writeSync(handler, magic_head, writePivot);
writePivot += magic_head.length;

console.log(`写入16字节文件版本号：${fileVersion}`);
writeLen = fs.writeSync(handler, fileVersion, writePivot);
writePivot += 16;

console.log(`写入2字节总字数: ${fileMapper.length}`);
fs.writeSync(handler, prefixHexInteger(fileMapper.length, 4), 0, 2, writePivot);
writePivot += 2;

function toHexString(byteArray) {
    return Array.from(byteArray, function(byte) {
      return ('0' + (byte & 0xFF).toString(16)).slice(-2);
    }).join('')
  }
  
console.log("开始写入文件数据=>");
let lastWordFilePivot = writePivot + maxWordCount * 6;
for(m of fileMapper) {
    const file = resourceDir + m.file;
    if(!fs.existsSync(file)) {
        throw new Error(`找不到文件：${file}`)
    }
    let wordGPK = iconv.encode(m.word, 'GBK');
    console.log(`写入: \"${m.word}\" + ${toHexString(wordGPK)} ${wordGPK.length}字节`);
    //let wordStr = m.word.codePointAt(0).toString(16);
    //let wordUnicode = Buffer.from(wordStr, "hex");
    //console.log(`写入: \"${m.word}\" ${wordUnicode.length}字节`)
    //fs.writeSync(handler, wordUnicode, 0, 2, writePivot);
    fs.writeSync(handler, wordGPK, 0, 2, writePivot);
    writePivot += 2;

    let stat = fs.statSync(file);
    let fileLength = stat.size;
    if(fileLength < 0) {
        throw new Error(`文件${file}的长度为0`)
    }
    
    //console.log(`写入${file}文件长度: ${prefixHexInteger(fileLength, 4)}`);
    console.log(`写入${file}的文件长度: ${fileLength}`);
    fs.writeSync(handler, prefixHexInteger(fileLength, 4), 0, 2, writePivot);
    writePivot += 2;

    console.log(`写入${file}的偏移量: ${lastWordFilePivot}`);
    //console.log(`写入${file}文件长度: ${prefixHexInteger(fileLength, 4)}`);
    fs.writeSync(handler, prefixHexInteger(lastWordFilePivot, 4), 0, 2, writePivot);
    writePivot += 2;

    console.log(`写入${file}的文件数据: ${fileLength}字节`);
    let wordFileBuffer = fs.readFileSync(file);
    fs.writeSync(handler, wordFileBuffer, 0, fileLength, lastWordFilePivot);
    lastWordFilePivot += fileLength;

    console.log('\r');
}